package com.common.db;

import android.content.Context;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import com.common.R;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 使用方式
 * SQLiteDatabase db = DatabaseManager.getInstance(context).getDatabase();
 * if (db.isOpen()) {
 * // 执行复杂查询并返回结果
 * String query = "SELECT COUNT(*) FROM items";
 * try (Cursor cursor = db.rawQuery(query, null)) {
 * if (cursor.moveToFirst()) {
 * return cursor.getInt(0);
 * }
 * }
 */
public class DatabaseManager {
    private static final String TAG = "DatabaseManager";
    private static final String DATABASE_NAME = "dengpp.db";
    private static final int DATABASE_VERSION = 1;

    private static DatabaseManager instance;
    private SQLiteDatabase db;
    private Context appContext;
    private int currentVersion;

    private DatabaseManager(Context context) {
        appContext = context.getApplicationContext();

        // 先复制数据库文件（如果需要）
        copyDatabaseIfNeeded();

        // 再打开数据库
        openDatabase();
    }

    public static synchronized DatabaseManager getInstance(Context context) {
        if (instance == null) {
            instance = new DatabaseManager(context);
        }
        return instance;
    }

    /**
     * 检查并复制数据库文件（如果不存在或版本需要更新）
     */
    private void copyDatabaseIfNeeded() {
        File dbFile = appContext.getDatabasePath(DATABASE_NAME);

        try {
            // 情况1：数据库文件不存在，直接复制
            if (!dbFile.exists()) {
                Log.d(TAG, "数据库文件不存在，开始复制...");
                copyDatabaseFromRaw();

                // 复制后设置版本号
                setDatabaseVersionAfterCopy();
                return;
            }

            // 情况2：数据库文件存在，检查版本
            // 临时打开数据库获取版本信息
            SQLiteDatabase tempDb = SQLiteDatabase.openDatabase(
                    dbFile.getPath(),
                    null,
                    SQLiteDatabase.OPEN_READONLY
            );

            int fileVersion = tempDb.getVersion();
            tempDb.close();

            Log.d(TAG, "现有数据库版本: " + fileVersion);

            // 如果现有版本低于代码中的版本，删除并重新复制
            if (fileVersion < DATABASE_VERSION) {
                Log.d(TAG, "数据库版本需要更新，删除旧文件并重新复制...");
                if (dbFile.delete()) {
                    copyDatabaseFromRaw();

                    // 复制后设置版本号
                    setDatabaseVersionAfterCopy();
                } else {
                    Log.e(TAG, "无法删除旧数据库文件");
                    throw new IOException("无法更新数据库");
                }
            }

        } catch (Exception e) {
            Log.e(TAG, "复制数据库失败", e);
            throw new RuntimeException("初始化数据库失败", e);
        }
    }

    /**
     * 从RAW资源复制数据库文件
     */
    private void copyDatabaseFromRaw() {
        try {
            File dbDir = appContext.getDatabasePath(DATABASE_NAME).getParentFile();
            if (!dbDir.exists() && !dbDir.mkdirs()) {
                Log.e(TAG, "创建数据库目录失败");
                throw new IOException("无法创建数据库目录");
            }

            InputStream inputStream = appContext.getResources().openRawResource(R.raw.dengpp);

            FileOutputStream outputStream = new FileOutputStream(
                    appContext.getDatabasePath(DATABASE_NAME)
            );

            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) > 0) {
                outputStream.write(buffer, 0, length);
            }

            outputStream.flush();
            outputStream.close();
            inputStream.close();

            Log.d(TAG, "数据库文件复制成功");
        } catch (Exception e) {
            Log.e(TAG, "复制数据库文件失败", e);
            throw new RuntimeException("复制数据库文件失败", e);
        }
    }

    /**
     * 复制完成后设置数据库版本
     */
    private void setDatabaseVersionAfterCopy() {
        Log.d(TAG, "设置复制后的数据库版本为: " + DATABASE_VERSION);

        // 打开数据库并设置版本
        SQLiteDatabase tempDb = null;
        try {
            tempDb = SQLiteDatabase.openDatabase(
                    appContext.getDatabasePath(DATABASE_NAME).getPath(),
                    null,
                    SQLiteDatabase.OPEN_READWRITE
            );

            tempDb.setVersion(DATABASE_VERSION);
            Log.d(TAG, "数据库版本设置成功");
        } catch (Exception e) {
            Log.e(TAG, "设置数据库版本失败", e);
            throw new RuntimeException("设置数据库版本失败", e);
        } finally {
            if (tempDb != null && tempDb.isOpen()) {
                tempDb.close();
            }
        }
    }

    /**
     * 打开数据库并验证版本
     */
    private void openDatabase() {
        try {
            File dbFile = appContext.getDatabasePath(DATABASE_NAME);

            if (!dbFile.exists()) {
                throw new IOException("数据库文件不存在，可能复制失败");
            }

            db = SQLiteDatabase.openOrCreateDatabase(
                    dbFile.getPath(),
                    null,
                    new DatabaseErrorHandler() {
                        @Override
                        public void onCorruption(SQLiteDatabase dbObj) {
                            Log.e(TAG, "数据库损坏: " + dbObj.getPath());
                            deleteDatabase();
                            copyDatabaseIfNeeded();
                            openDatabase();
                        }
                    }
            );

            Log.d(TAG, "数据库打开成功");

            // 获取当前版本
            currentVersion = db.getVersion();
            Log.d(TAG, "当前数据库版本: " + currentVersion);

            // 验证版本是否正确
            if (currentVersion != DATABASE_VERSION) {
                Log.w(TAG, "数据库版本不匹配，可能文件已损坏，重新复制...");
                deleteDatabase();
                copyDatabaseIfNeeded();
                openDatabase(); // 重新打开
            }

        } catch (Exception e) {
            Log.e(TAG, "打开数据库失败", e);
            throw new RuntimeException("无法打开数据库", e);
        }
    }

    /**
     * 删除数据库文件
     */
    private void deleteDatabase() {
        File dbFile = appContext.getDatabasePath(DATABASE_NAME);
        if (dbFile.exists()) {
            if (db != null && db.isOpen()) {
                db.close();
            }
            if (appContext.deleteDatabase(DATABASE_NAME)) {
                Log.d(TAG, "数据库删除成功");
            } else {
                Log.e(TAG, "数据库删除失败");
            }
        }
    }

    /**
     * 获取数据库实例
     */
    public SQLiteDatabase getDatabase() {
        if (db == null || !db.isOpen()) {
            openDatabase();
        }
        return db;
    }

    /**
     * 关闭数据库
     */
    public void closeDatabase() {
        if (db != null && db.isOpen()) {
            db.close();
            db = null;
            Log.d(TAG, "数据库已关闭");
        }
    }

    /**
     * 检查数据库是否存在
     */
    public boolean isDatabaseExists() {
        File dbFile = appContext.getDatabasePath(DATABASE_NAME);
        return dbFile.exists();
    }

    /**
     * 获取当前数据库版本
     */
    public int getDatabaseVersion() {
        return currentVersion;
    }
}